#include "brick.h"

/*******************************************************************
*
*	Constructor
*
********************************************************************/
Brick::Brick(float posX, float posY, float width, float height, Resources* res, int number, int depth)
:GameObject(posX, posY, width, height, res, number, depth)
{
	_sprite = new Sprite(_resources->Brick, 2, 2, 0);
	_sprite->Next(0);

	_id = ID::ID_Brick;
	_state = BRICK_STATE::BRICK_NORMAL;

	_vel_y = _acc_y = _Ax = _Ay = _Bx = _By = _acc_y_break = 0;
	_Ax1 = _Bx1 = _vel_Ax1 = _vel_Bx1 = 0;
	_angle = 0;

	_old_y = _pos_y;
	_isStatic = true;
}

/*******************************************************************

********************************************************************/
Brick::~Brick(void)
{
}

/*******************************************************************
*
*	Update
*
********************************************************************/
void Brick::Update(float time, QNode* &Tree)
{
	switch (_state)
	{
	case BRICK_STATE::BRICK_NORMAL:
		_vel_y = _acc_y = _Ax = _Ay = _Bx = _By = _Ax1 = _Bx1 = _acc_y_break = 0;
		_angle = 0;
		break;
	case BRICK_STATE::BRICK_MOVEUP:
		_vel_y += _acc_y * time;
		_pos_y -= _vel_y * time + 0.5f * _acc_y * time * time;

		if (_pos_y < _old_y)
			ChangeState(BRICK_STATE::BRICK_NORMAL);
		break;
	case BRICK_STATE::BRICK_BREAK:
		_sprite->Next(1);

		_Ax += _vel_Ax * time;
		_Bx += _vel_Bx * time;

		_Ax1 += _vel_Ax1 * time;
		_Bx1 += _vel_Bx1 * time;

		_vel_Ay += _acc_y_break * time;
		_vel_By += _acc_y_break * time;

		_Ay -= _vel_Ay * time + 0.5f * _acc_y_break * time * time;
		_By -= _vel_By * time + 0.5f * _acc_y_break * time * time;

		_angle += 0.2f;
		break;
	default:
		break;
	}
	_old_rect = _rect;
	ResetRect();

	// change state to delete brick
	if (_Ay < 0)
		_isAlive = false;
}

/*******************************************************************
*
*	Render
*
********************************************************************/
void Brick::Render(LPD3DXSPRITE spriteHandler, Viewport* viewport)
{
	if (_state == BRICK_STATE::BRICK_NORMAL || _state == BRICK_STATE::BRICK_MOVEUP)
	{
		_sprite->Render(spriteHandler, _pos_x, _pos_y, false, viewport);
	}
	else if (_state == BRICK_STATE::BRICK_BREAK)
	{
		_sprite->Render(spriteHandler, _Ax, _Ay, 1, 1, _angle, viewport);
		_sprite->Render(spriteHandler, _Bx, _By, 1, 1, _angle, viewport);
		_sprite->Render(spriteHandler, _Ax1, _Ay + _width / 2, 1, 1, -_angle, viewport);
		_sprite->Render(spriteHandler, _Bx1, _By + _width / 2, 1, 1, -_angle, viewport);
	}
}

/*******************************************************************
*
*	Change State
*
********************************************************************/
void Brick::ChangeState(char state)
{
	if (_state == BRICK_STATE::BRICK_BREAK)
		return;

	_state = state;

	switch (_state)
	{
	case BRICK_STATE::BRICK_NORMAL:
		_vel_y = 0;
		_acc_y = 0;
		_pos_y = _old_y;
		break;
	case BRICK_STATE::BRICK_MOVEUP:
		_vel_y = -VEL_Y;
		_acc_y = GRAVITY;
		break;
	case BRICK_STATE::BRICK_BREAK:
		_width = _height = 0;
		_Ax = _Ax1 = _pos_x;
		_Bx = _Bx1 = _pos_x + _width / 2;
		_Ay = _pos_y;
		_By = _pos_y + _height / 2;

		_vel_Ax = BRICK_V_AX;
		_vel_Bx = BRICK_V_BX;
		_vel_Ax1 = -BRICK_V_AX;
		_vel_Bx1 = -BRICK_V_BX;
		_vel_Ay = -BRICK_V_AY;
		_vel_By = -BRICK_V_BY;
		_acc_y_break = GRAVITY;
		break;
	default:
		break;
	}
}